package com.ksframework.common.dao;

import java.io.Serializable;
import java.util.Collection;
import java.util.List;
import java.util.Map;

import org.hibernate.Criteria;
import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.criterion.Criterion;
import org.hibernate.criterion.Order;

import com.ksframework.common.entity.BaseEntity;
import com.ksframework.common.exception.DAOException;

public interface IBaseHibernateDao<T> {

	public Session getHibernateSession();

	/**
	 * 根据实体ID获取实体对象.
	 * @param clazz 需要获取的对象类型
	 * @param id 序列化后的ID
	 * @return	实体对象.
	 */
	public Object get(Class<?> clazz, Serializable id) throws DAOException;

	/**
	 * load对象
	 * @param clazz 对象类型
	 * @param id ID
	 * @return 实体对象
	 */
	public Object load(Class<?> clazz, final Serializable id) throws DAOException;

	/**
	 * 根据hql语句查找唯一对象.
	 * @param hql hql语句
	 * @param values 参数
	 * @return 对象
	 */
	public Object findUnique(String hql, Object... values) throws DAOException;

	/**
	 * 根据属性查找唯一对象.
	 * @param clazz 对象类型
	 * @param propertyName 属性名
	 * @param value 属性值
	 * @return 对象
	 */
	public Object findUniqueByProperty(Class<?> clazz, String propertyName, Object value) throws DAOException;

	/*
	 * 通过属性查找唯一的对象(non-Javadoc)
	 */
	public Object findUniqueByPropertyOrder(Class<?> clazz, String propertyName, Object value, Order... orders) throws DAOException;

	/**
	 * 获取实体全部列表(loadAll方式).可排序.
	 * @param clazz 实体类型
	 * @return 返回实体列表.
	 */
	public List<?> getAll(Class<?> clazz, Order... orders) throws DAOException;

	/**
	 * 获取实体全部列表(criteria方式)，推荐使用这种方式.
	 * 不带条件查询，不带排序。
	 * @param clazz 实体类型
	 * @see #findByCriteria(Class, Criterion[])
	 * @return 返回实体列表.
	 */
	public List<?> getAllListByCriteria(Class<?> clazz) throws DAOException;

	/**
	 * 获取实体全部列表(criteria方式)。
	 * 支持多个字段排序
	 * @param clazz
	 * @param orders
	 * @return
	 * @throws DAOException
	 */
	public List<?> getAllByCriteriaOrder(Class<?> clazz, Order... orders) throws DAOException;

	/**
	 * 获取实体全部分页列表.
	 * 使用criteria方式查找.
	 * @param clazz 实体类型	
	 * @param page
	 * @see #findByCriteria(Class clazz,Page page, Criterion... criterion)
	 * @return 分页查询结果
	 */
	public Page<?> getAllBycriteria(Class<?> clazz, Page<?> page) throws DAOException;

	/**
	 * SaveOrUpdate
	 * @param entity
	 */
	public void saveOrUpdate(Object entity) throws DAOException;

	/**
	 * save
	 * @param entity
	 * @return  实体对象.
	 */
	public Object save(Object entity) throws DAOException;

	/**
	 * update
	 * @param entity
	 */
	public void update(Object entity) throws DAOException;

	/**
	 * merge
	 * @param entity
	 * @return 实体
	 */
	public Object merge(Object entity) throws DAOException;

	/**
	 * persist方式保存
	 * @param entity
	 */
	public void persist(Object entity) throws DAOException;

	/**
	 * 根据对象删除
	 * @param entity
	 */
	public void delete(Object entity) throws DAOException;

	/**
	 * 根据指定的单条件删除对象
	 * @param clazz
	 * @param propertyName
	 * @param value
	 * @throws DAOException
	 */
	public void deleteByProperty(Class<?> clazz, String propertyName, Serializable value) throws DAOException;

	/**
	 * 单条件模糊查询删除对象
	 * @param clazz
	 * @param propertyName
	 * @param value
	 * @throws DAOException
	 */
	public void deleteByLike(Class<?> clazz, String propertyName, Serializable value) throws DAOException;

	/**
	 * 多条件查询删除
	 * @param clazz
	 * @param filter
	 * @throws DAOException
	 */
	public void deleteByMap(Class<?> clazz, Map<String, Object> filter) throws DAOException;

	/**
	 * 删除集合中的所有对象
	 * @param collection
	 * @throws DAOException
	 */
	public void deleteAll(Collection<?> collection) throws DAOException;

	/**
	 * 批量删除对象
	 * @param clazz	实例类型
	 * @param ids	对象ID集合
	 * @throws Exception 
	 */
	public void batchDelete(Class<?> clazz, final Serializable[] ids) throws DAOException;

	/**
	 * 批量保存或更新
	 * @param clazz
	 * @param list
	 * @throws DAOException
	 */
	public void batchSaveOrUpdate(final List<?> list) throws DAOException;

	/**
	 * 根据对象ID删除
	 * @param clazz 实体类型
	 * @param id 实体ID
	 */
	public void delete(Class<?> clazz, Serializable id) throws DAOException;

	/**
	 * flush 
	 *
	 */
	public void flush() throws DAOException;

	/**
	 * 清空指定对象缓存
	 * @param entity
	 */
	public void clearCache(Object entity) throws DAOException;

	/**
	 * 清空所有缓存
	 *
	 */
	public void clearAllCache() throws DAOException;

	/**
	 * 重新初始化proxy实体.
	 * @param proxy
	 */
	public void reloadLazy(Object proxy) throws DAOException;

	/**
	 * 使用HQL方式查找对象列表.
	 * @param hql
	 * @param values
	 * @return
	 */
	public List<?> findByHql(String hql, Object... values) throws DAOException;

	/**
	 * 使用SQL方式查找对象列表
	 * @param sql
	 * @return
	 * @throws DAOException
	 */
	public List<?> findBySql(String sql) throws DAOException;

	/*
	 * 通过属性查找(non-Javadoc)
	 * @see com.dk.dao.IGenericDAO#findByProperty(java.lang.String, java.lang.Object, org.hibernate.criterion.Order[])
	 */
	public List<?> findByProperty(Class<?> clazz, String property, Object value, Order... orders) throws DAOException;

	/*
	 * 通过 %like% 查找(non-Javadoc)
	 * @see com.dk.dao.IGenericDAO#findByLike(java.lang.String, java.lang.String, org.hibernate.criterion.Order[])
	 */
	public List<?> findByLike(Class<?> clazz, String field, String keyWord, Order... orders) throws DAOException;

	/*
	 * 通过Map<String,Object>查找,在Map可设置多个参数(non-Javadoc)
	 * @see com.dk.dao.IGenericDAO#findByMap(java.util.Map, org.hibernate.criterion.Order[])
	 */
	public List<?> findByMap(Class<?> clazz, Map<String, Object> filter, Order... orders) throws DAOException;

	/**
	 * 根据Criterion条件创建Criteria,后续可进行更多处理,辅助函数. 
	 * @param clazz 实体类型
	 * @param criterion
	 * @return
	 */
	public List<?> findByCriteria(Class<?> clazz, Criterion... criterion) throws DAOException;

	/**
	 * 根据Criterion条件创建Criteria,后续可进行更多处理,辅助函数. 
	 * @notice 增加一个可选参数Order[]
	 * @param clazz
	 * @param criterion
	 * @param order2
	 * @return
	 * @throws DAOException
	 */
	public List<?> findByCriteria(Class<?> clazz, Criterion[] criterion, Order... order2) throws DAOException;

	/***
	 * 按Criteria查询列表
	 * @主要功能：
	 * @author: Snoopy Chen (ctfzh@yahoo.com.cn)
	 * @since： Jun 9, 2009 
	 * @param c 查询条件
	 * @return
	 * @throws DAOException
	 */
	public List<?> findByCriteriaSession(Criteria c) throws DAOException;

	/**
	 *  根据查询函数与参数列表创建Query对象,后续可进行更多处理,辅助函数.
	 * @param queryString
	 * @param values
	 * @return
	 */
	public Query createQuery(String queryString, Object... values) throws DAOException;

	/**
	 * 根据Criterion条件创建Criteria,后续可进行更多处理,辅助函数.
	 * HQL运算符 QBC运算符 含义
		= Restrictions.eq() 等于
		<> Restrictions.not(Exprission.eq()) 不等于
		> Restrictions.gt() 大于
		>= Restrictions.ge() 大于等于
		< Restrictions.lt() 小于
		<= Restrictions.le() 小于等于
		is null Restrictions.isnull() 等于空值
		is not null Restrictions.isNotNull() 非空值
		like Restrictions.like() 字符串模式匹配
		and Restrictions.and() 逻辑与
		and Restrictions.conjunction() 逻辑与
		or Restrictions.or() 逻辑或
		or Restrictions.disjunction() 逻辑或
		not Restrictions.not() 逻辑非
		in(列表) Restrictions.in() 等于列表中的某一个值
		ont in(列表) Restrictions.not(Restrictions.in())不等于列表中任意一个值
		between x and y Restrictions.between() 闭区间xy中的任意值
		not between x and y Restrictions.not(Restrictions..between()) 小于值X或者大于值y
	 * @param clazz 对象类型
	 * @param criteria
	 */
	public Criteria createCriteria(Class<?> clazz, Criterion... criterions) throws DAOException;

	/**
	 * 按Criterion分页查询.
	 * @param clazz 实体类型
	 * @param page 分页参数.包括pageSize、firstResult、orderBy、asc、autoCount.
	 *             其中firstResult可直接指定,也可以指定pageNo.
	 *             autoCount指定是否动态获取总结果数.
	 *             
	 * @param criterion 数量可变的Criterion.
	 * @param see {@link #countQueryResult(Page, Criteria)}
	 * @return 分页查询结果.附带结果列表及所有查询时的参数.
	 */
	public Page<?> findByCriteria(Class<?> clazz, Page<?> page, Criterion... criterion) throws DAOException;

	/**
	 * 按Criterion分页查询,可级联查询,需要传入级联对象别名,别名用逗号分开,如"user,u".
	 * @author: Terry
	 * @since： Jun 21, 2009 
	 * @param clazz 实体类型
	 * @param page 分页参数.包括pageSize、firstResult、orderBy、asc、autoCount.
	 *             其中firstResult可直接指定,也可以指定pageNo.
	 *             autoCount指定是否动态获取总结果数.
	 *             
	 * @param criterion 数量可变的Criterion.
	 * @param see {@link #countQueryResult(Page, Criteria)}
	 * @return 分页查询结果.附带结果列表及所有查询时的参数.
	 */
	public Page<?> findByCriteriaCascade(Class<?> clazz, Page<?> page, String[] alias, Criterion... criterions) throws DAOException;

	/***
	 * @主要功能：按Criteria分页查询.
	 * @author: ctf 陈廷峰
	 * @since： Jun 2, 2009 
	 * @param clazz 实体类型
	 * @param page 分页参数.包括pageSize、firstResult、orderBy、asc、autoCount.
	 *             其中firstResult可直接指定,也可以指定pageNo.
	 *             autoCount指定是否动态获取总结果数.
	 * @param c Criteria类型的查询条件
	 * @return 分页查询结果.附带结果列表及所有查询时的参数.
	 * @see {@link #countQueryResult(Page, Criteria)}
	 * @throws DAOException
	 */
	public Page<?> findByCriteriaSession(Class<?> clazz, Page<?> page, Criteria c) throws DAOException;

	/**
	 * 按Criteria 别名分页查询，用于多表关联查询
	 * @param clazz
	 * @param page
	 * @param alias
	 * @param criterion
	 * @return
	 * @throws DAOException
	 */
	public Page<?> findByCriteriaWithAlias(Class<?> clazz, Page<?> page, String[] alias, Criterion... criterion) throws DAOException;

	/**
	 * 分页查找,可排序
	 * @param page
	 * @param order
	 * @param criteria
	 * @return
	 * @throws DAOException
	 */
	public Page<?> findAndPagination(Page<?> page, Order order, Criteria criteria) throws DAOException;

	/**
	 * 分页查询，可排序
	 * @param clazz
	 * @param page
	 * @param order
	 * @param restrictions
	 * @return
	 * @throws DAOException
	 */
	public Page<?> findAndPagination(Class<?> clazz, Page<?> page, Order order, Criterion[] restrictions) throws DAOException;

	/**
	 * 根据实体ID查找实体对象集合.
	 */
	public List<?> findEntitysByIds(Class<?> clazz, Collection<Serializable> values) throws DAOException;

	/**
	 * 根据ID集合查找对应对象集合.
	 */
	public List<?> findEntitys(List<? extends BaseEntity> values) throws DAOException;

}